#pragma once

#include <string>

#include "../SQLExpr.h"
#include "../SQLExprImpl.h"
#include "../SQLOver.h"
#include "SQLMethodInvokeExpr.h"
#include "../SQLReplaceable.h"

class SQLASTVisitor;

// enum SQLAggregateExpr_Option
// {
//   DISTINCT,
//   ALL,
//   UNIQUE
// };

class SQLAggregateExpr
    : virtual public SQLMethodInvokeExpr,
      virtual public SQLReplaceable
{
protected:
  string_ptr methodName;
  std::shared_ptr<SQLAggregateOption> option;
  SQLExpr_list_ptr arguments;
  SQLOver_ptr over;
  void acceptChild(SQLASTVisitor_ptr visitor, SQLOver_ptr children);
  void acceptChild(SQLASTVisitor_ptr visitor, SQLExpr_list_ptr children);

public:
  static string_ptr class_;
  SQLAggregateExpr(string_ptr methodName);
  virtual ~SQLAggregateExpr();

  SQLAggregateExpr(string_ptr methodName, std::shared_ptr<SQLAggregateOption> option);
  SHAREDOBJECT(SQLAggregateExpr);

  string_ptr getMethodName();

  void setMethodName(string_ptr methodName);

  std::shared_ptr<SQLAggregateOption> getOption();

  void setOption(std::shared_ptr<SQLAggregateOption> option);

  SQLExpr_list_ptr getArguments();

  SQLOver_ptr getOver();

  void setOver(SQLOver_ptr over);
  BOOL_ptr isIgnoreNulls();
  BOOL_ptr getIgnoreNulls();
  void setIgnoreNulls(BOOL_ptr ignoreNulls);
  BOOL_ptr isWithinGroup();
  void setWithinGroup(BOOL_ptr withinGroup);
  SQLKeep_ptr getKeep();
  void setKeep(SQLKeep_ptr keep);
  SQLName_ptr getOverRef();
  void setOverRef(SQLName_ptr x);
  SQLExpr_ptr getFilter();
  void setFilter(SQLExpr_ptr x);
  SQLOrderBy_ptr getOrderBy();
  void setOrderBy(SQLOrderBy_ptr orderBy);

protected:
  void accept0(SQLASTVisitor_ptr visitor);

public:
  // int hashCode();

  // BOOL_ptr equals(Object obj);
  BOOL_ptr ignoreNulls;
  BOOL_ptr withinGroup;
  SQLKeep_ptr keep;
  SQLName_ptr overRef;
  SQLExpr_ptr filter;
  SQLOrderBy_ptr orderBy;
};
